package com.weng.cloud.service8881.bean.lookup;

import com.weng.cloud.commons.base.JsonUtil;
import com.weng.cloud.service8881.bean.lookup.demo1.Car;
import com.weng.cloud.service8881.bean.lookup.demo1.Seat;
import com.weng.cloud.service8881.bean.lookup.demo2.Cmd;
import com.weng.cloud.service8881.bean.lookup.demo2.CmdMgr;
import com.weng.cloud.service8881.bean.lookup.demo2.DefaultCmd;
import com.weng.cloud.service8881.bean.lookup.demo3.FooBar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class TestLookupConfig implements ApplicationRunner {

    /**
     * demo1
     */

    @Bean
    public Car car() {
        Car car = new Car();
//        car.setName("红旗");
        car.setSeat(seat());
        return car;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Seat seat() {
        return new Seat();
    }

    /**
     * demo2
     */

    @Bean
    public CmdMgr cmdMgr() {
        return new CmdMgr() {
            @Override
            protected Cmd createCmd() {
                return defaultCmd();
            }
        };
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Cmd defaultCmd() {
        return new DefaultCmd();
    }

    @Lookup
    public FooBar fooBarNull() {
        return null;
    }

    /**
     * <br/>function: 有说法是@lookup方法会被代理，实际上是return null,离谱的是，我return all-args的构造并没有失效
     * <br/>tip:
     *
     * @param: [foo, bar]
     * @return: com.weng.cloud.service8881.bean.lookup.demo3.FooBar
     * @author: weng
     * @date: 2022/5/14 13:55
     */
    @Lookup
    public FooBar fooBarAll(String foo, Integer bar) {
        return new FooBar(foo, bar);
    }

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) throws Exception {
/*
        Car car = (Car) applicationContext.getBean("car");
        Seat seat = car.getSeat();
        Car car1 = (Car) applicationContext.getBean("car");
        Seat seat1 = car1.getSeat();
        System.out.println(seat == seat1);
*/

/*
        Car car1 = car();
        Car car2 = car();
        // true -> car注入过程的属性赋值时就已经初始化了一个seat -> 也就是说seat()方法只被调用一次 -> true
        System.out.println("没啥心情" + (car1.getSeat() == car2.getSeat()));

        Cmd cmd1 = cmdMgr().process("dream high");
        Cmd cmd2 = cmdMgr().process("reset");
        // false -> 这是因为 cmdMgr 扮演了 cmd 的工厂 -> defaultCmd()被多次调用 -> false
        System.out.println("停摆伤害挺大" + (cmd1 == cmd2));
*/


//        System.out.println("foo-bar"+(fooBarNull() == fooBarNull()));
        FooBar fb1 = fooBarAll("reset", 2015);
        FooBar fb2 = fooBarAll("dream high", 2011);
        System.out.println(JsonUtil.toText(fb1));
        System.out.println("foo-bar" + (fb1 == fb2));
    }
}